#ifndef MOCHA_DETAIL_GAME_HPP_INCLUDED
#define MOCHA_DETAIL_GAME_HPP_INCLUDED

/**
 * @file
 */

#include <boost/shared_ptr.hpp>
#include <boost/signal.hpp>
//#include <boost/signals/trackable.hpp>

namespace mocha {
/**
 * Base of game objects, which act as the primary interface to the core.
 * All Mocha based programs should derive from this base and implement its detailed functionality.
 */
class game {
public:
	/// Signal fired when the game is started.
	boost::signal<void(const game* const)> started;
	/// Signal fired when the game is stopped.
	boost::signal<void(const game* const)> stopped;
	game();
	virtual ~game();
	/**
	 * 
	 */
	void start();
	/**
	 * 
	 */
	void stop();
protected:
	/**
	 * Panics, stopping the game after some logging.
	 */
	void panic();
	/**
	 * Searches for events in the event queue and fires relevant signals from all subsystems.
	 * No events are removed from the queue.
	 */
	void peek_all_event_signals();
	/**
	 * Searches for events from the event queue and fires relevant signals from all subsystems.
	 * All relevant events are popped from the queue.
	 */
	void pop_all_event_signals();
	/**
	 * Called when the game is started. If overridden, this function should perform initialization.
	 * @return True if initialization was successful. If false is returned, the game is aborted, as this indicates that initialization failed.
	 * @see do_stop
	 */
	virtual bool do_start();
	/**
	 * Called when the game is stopped. If overriden, this function should perform deinitialization.
	 * @return True if deinitialization was successful. If false is returned, the game panics (this is not the same as a clean stop).
	 * @see do_start
	 */
	virtual bool do_stop();
	/**
	 * Called each time the game should update game logic.
	 * This member function must be overridden by subclasses and is called periodically.
	 * @param elapsed Elapsed ticks since the last update.
	 * @param factor Time factor at the time of the call. The time factor is the ratio of desired update interval to actual update interval. When multiplied with time sensitive operations (such as movement), it helps control the rate of updating.
	 * @see do_paint
	 */
	virtual void do_update(unsigned long elapsed, float factor) = 0;
	/**
	 * Called each time the game should be (re)painted.
	 * This member function must be overridden by subclasses.
	 * @see do_update
	 */
	virtual void do_paint() = 0;
private:
	void init();
	void deinit();
	void loop();
	void update();
	void paint();
	/// 
	int loop_flag_;
};
}

#endif

